package com.csaba.swing.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

import com.csaba.swing.MainWindow;
import com.csaba.swing.gui.util.DynamicColumnLayout;
import com.csaba.swing.model.Config;
import com.csaba.swing.model.Language;
import com.csaba.util.LoggerHelper;

@SuppressWarnings( "serial" )
public class PreferencesDialog extends JDialog
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();

	private JComboBox localeCombo;
	private JComboBox lafCombo;
	private JTextField proxyHostField;
	private JTextField proxyPortField;
	private JComboBox logLevelCombo;
	private JCheckBox fileLoggingCheckbox;
	private JCheckBox openOnStartupCheckbox;

	private LAFWrapper[] lafs;

	public PreferencesDialog( final Frame owner )
	{
		super(owner);

		setModal(true);
		setTitle(MainWindow.getString("PreferencesDialog.title")); //$NON-NLS-1$
		setResizable(false);

		final AbstractAction loginAction = new AbstractAction(MainWindow.getString("PreferencesDialog.button.apply")) //$NON-NLS-1$
		{
			@Override
			public void actionPerformed( final ActionEvent arg0 )
			{
				apply();
			}
		};

		//create input fields
		final JPanel inputs = new JPanel(new DynamicColumnLayout(new int[] { DynamicColumnLayout.LEFT,
				DynamicColumnLayout.LEFT }));

		inputs.setBorder(BorderFactory.createEmptyBorder());
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.locale"))); //$NON-NLS-1$
		inputs.add(localeCombo = new JComboBox(Language.getAvailableLanguages()));
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.lookAndFeel"))); //$NON-NLS-1$
		inputs.add(lafCombo = new JComboBox(lafs = convert(UIManager.getInstalledLookAndFeels())));
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.proxyHost"))); //$NON-NLS-1$
		inputs.add(proxyHostField = new JTextField(30));
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.proxyPort"))); //$NON-NLS-1$
		inputs.add(proxyPortField = new JTextField(30));
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.fileLogging"))); //$NON-NLS-1$
		inputs.add(fileLoggingCheckbox = new JCheckBox());
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.logLevel"))); //$NON-NLS-1$
		inputs.add(logLevelCombo = new JComboBox(new Level[] { Level.ALL, Level.FINEST, Level.FINER, Level.FINE,
				Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF }));
		inputs.add(new JLabel(MainWindow.getString("PreferencesDialog.openEncrypt"))); //$NON-NLS-1$
		inputs.add(openOnStartupCheckbox = new JCheckBox());

		//fill data
		localeCombo.setSelectedItem(Language.getLanguageByCode(Config.getInstance().getLocale()));
		for ( final LAFWrapper laf : lafs )
		{
			if ( laf.getClassName().equals(Config.getInstance().getLookAndFeel()) )
			{
				lafCombo.setSelectedItem(laf);
				break;
			}
		}

		proxyHostField.setText(Config.getInstance().getHttpsProxyHost());
		proxyPortField.setText(Config.getInstance().getHttpsProxyPort());
		logLevelCombo.setSelectedItem(Config.getInstance().getLogLevel());
		fileLoggingCheckbox.setSelected(Config.getInstance().isFileLogging());
		openOnStartupCheckbox.setSelected(Config.getInstance().isOpenOnStartup());

		//create buttons
		final JPanel buttons = new JPanel(new FlowLayout());
		final JButton login = new JButton(loginAction);
		buttons.add(login);

		final JButton cancel = new JButton(new AbstractAction(MainWindow.getString("PreferencesDialog.button.cancel")) //$NON-NLS-1$
				{
					@Override
					public void actionPerformed( final ActionEvent e )
					{
						dispose();
					}

				});
		buttons.add(cancel);

		//create content
		final JPanel content = (JPanel) getContentPane();
		content.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		content.setLayout(new BorderLayout());
		content.add(inputs, BorderLayout.CENTER);
		content.add(buttons, BorderLayout.SOUTH);

		pack();
		setLocationRelativeTo(owner);
	}

	protected void apply()
	{
		final Config config = Config.getInstance();
		config.setLocale(( (Language) localeCombo.getSelectedItem() ).getCode());
		config.setHttpsProxyHost(proxyHostField.getText());
		config.setHttpsProxyPort(proxyPortField.getText());
		config.setLogLevel((Level) logLevelCombo.getSelectedItem());
		config.setFileLogging(fileLoggingCheckbox.isSelected());
		config.setOpenOnStartup(openOnStartupCheckbox.isSelected());
		config.setLookAndFeel(( (LAFWrapper) lafCombo.getSelectedItem() ).getClassName());
		try
		{
			Config.saveConfig();
			dispose();
		}
		catch ( final IOException ex )
		{
			logger.log(Level.SEVERE, "Error saving config file.", ex); //$NON-NLS-1$
			JOptionPane
					.showMessageDialog(
							this,
							MainWindow.getString("PreferencesDialog.msg.saveProblem") + ex.getMessage(), MainWindow.getString("PreferencesDialog.title.error"), //$NON-NLS-1$ //$NON-NLS-2$
							JOptionPane.ERROR_MESSAGE);
		}
	}

	private LAFWrapper[] convert( final LookAndFeelInfo[] lafs )
	{
		final LAFWrapper[] lafws = new LAFWrapper[lafs.length];
		for ( int i = 0; i < lafs.length; i++ )
		{
			lafws[i] = new LAFWrapper(lafs[i].getName(), lafs[i].getClassName());
		}
		return lafws;
	}

	class LAFWrapper
	{
		String name;
		String className;

		public LAFWrapper( final String name, final String className )
		{
			this.name = name;
			this.className = className;
		}

		public String getName()
		{
			return name;
		}

		public String getClassName()
		{
			return className;
		}

		@Override
		public String toString()
		{
			return name;
		}

	}
}
